package com.siemens.industrial.web.mvc.service.partner;

import com.siemens.industrial.model.partner.DeviceShiftRelation;
import com.siemens.industrial.model.partner.User;
import com.siemens.industrial.utils.DateUtil;
import com.siemens.industrial.web.mvc.dao.partner.PartnerDeviceShiftRelationDao;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by qupen on 2016/8/31.
 */
@Service
public class PartnerShiftService {
    @Resource
    PartnerDeviceShiftRelationDao partnerDeviceShiftRelationDao;

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Transactional
    public void saveDeviceShift(String tenantId, User user, Map<String, Object> data) throws ParseException {
        Date beginDate = simpleDateFormat.parse(data.get("startDate").toString());
        Date endDate = simpleDateFormat.parse(data.get("endDate").toString());
        List<Map<String, Object>> shifts = (List<Map<String, Object>>) data.get("shift");
        List<Map<String, Object>> intersections = this.getBetween(tenantId, beginDate, endDate);
        if (intersections.size() == 0) {
            this.insert(tenantId, shifts, user, beginDate, endDate);
        } else {
            Date firstBeginTime = simpleDateFormat.parse(intersections.get(0).get("begin_date").toString());
            Date firstEndTime = simpleDateFormat.parse(intersections.get(0).get("end_date").toString());
            Date lastStartTime = simpleDateFormat.parse(intersections.get(intersections.size() - 1).get("begin_date").toString());
            Date lastEndTime = simpleDateFormat.parse(intersections.get(intersections.size() - 1).get("end_date").toString());

            if ((beginDate.before(firstBeginTime) || beginDate.equals(firstBeginTime)) && (endDate.after(lastEndTime) || endDate.equals(lastEndTime))) {
                //// TODO: 2016/11/23  1 可用
                this.deleteAll(intersections, tenantId);
                this.insert(tenantId, shifts, user, beginDate, endDate);
            } else if ((beginDate.after(firstBeginTime) && (beginDate.before(firstEndTime) || beginDate.equals(firstEndTime))) && (endDate.after(lastEndTime) || endDate.equals(lastEndTime))) {
                //// TODO: 2016/11/23  2 (beginDate.after(firstBeginTime)&&(beginDate.before(firstEndTime)||beginDate.equals(firstEndTime)))&&(endDate.after(lastEndTime)||endDate.equals(lastEndTime))
                List<Map<String, Object>> otherShifts = this.shiftListByBeginDate(tenantId, firstBeginTime);
                this.deleteAll(intersections, tenantId);
                this.insert(tenantId, shifts, user, firstBeginTime, DateUtil.lessOrAddDay(beginDate,-1));//之前结束时间jianshao少一天
                this.insert(tenantId, otherShifts, user, beginDate, endDate);
            } else if ((beginDate.before(firstBeginTime) || beginDate.equals(firstBeginTime)) && (endDate.before(lastEndTime) && (endDate.equals(lastStartTime) || endDate.after(lastStartTime)))) {
                //// TODO: 2016/11/23  3 (beginDate.before(firstBeginTime)||beginDate.equals(firstBeginTime))&&(endDate.before(lastEndTime)&&(endDate.equals(lastStartTime)||endDate.after(lastStartTime))
                List<Map<String, Object>> otherShifts = this.shiftListByEndDate(tenantId, lastEndTime);
                this.deleteAll(intersections, tenantId);
                this.insert(tenantId, shifts, user, beginDate, endDate);
                this.insert(tenantId, otherShifts, user, endDate, DateUtil.lessOrAddDay(lastEndTime,+1));
            } else if ((beginDate.after(firstBeginTime) && (beginDate.before(firstEndTime) || beginDate.equals(firstEndTime))) && (endDate.before(lastEndTime) && (endDate.equals(lastStartTime) || endDate.after(lastStartTime)))) {
                //// TODO: 2016/11/23  4 (beginDate.after(firstBeginTime)&&(beginDate.before(firstEndTime)||beginDate.equals(firstEndTime)))&&(endDate.before(lastEndTime)&&(endDate.equals(lastStartTime)||endDate.after(lastStartTime))
                List<Map<String, Object>> otherStartShifts = this.shiftListByBeginDate(tenantId, firstBeginTime);
                List<Map<String, Object>> otherEndShifts = this.shiftListByEndDate(tenantId, lastEndTime);
                this.deleteAll(intersections, tenantId);
                this.insert(tenantId, otherStartShifts, user, firstBeginTime,DateUtil.lessOrAddDay(beginDate,-1));
                this.insert(tenantId, shifts, user, beginDate, endDate);
                this.insert(tenantId, otherEndShifts, user, DateUtil.lessOrAddDay(endDate,+1),lastEndTime);
            }
        }
    }

    public boolean check(String tenantId, String startTime, String endTime) {

        return partnerDeviceShiftRelationDao.isExist(tenantId, startTime, endTime);
    }

    public List<Map<String, Object>> getBetween(String tenantId, Date startTime, Date endTime) {

        return partnerDeviceShiftRelationDao.getExist(tenantId, startTime, endTime);
    }

    public void insert(String tenantId, List<Map<String, Object>> shiftArr, User user, Date startDate, Date endDate) {
        for (Map<String, Object> shift : shiftArr) {
            DeviceShiftRelation deviceShiftRelation = new DeviceShiftRelation();
            String startTime = shift.get("shift-start").toString();
            String endTime = shift.get("shift-end").toString();
            String shiftName = shift.get("shift-name").toString();
            String shiftUser = shift.get("shift-user").toString();
            deviceShiftRelation.setStartTime(startTime);
            deviceShiftRelation.setEndTime(endTime);
            deviceShiftRelation.setUserId(user.getUserId());
            deviceShiftRelation.setPlan(1);
            deviceShiftRelation.setShiftName(shiftName);
            deviceShiftRelation.setShiftLead(shiftUser);
            deviceShiftRelation.setBeginDate(startDate);
            deviceShiftRelation.setEndDate(endDate);

            partnerDeviceShiftRelationDao.save(tenantId, deviceShiftRelation);
        }
    }

    public void deleteAll(List<Map<String, Object>> intersections, String tenantId) throws ParseException {
        for (Map<String, Object> intersection : intersections) {
            String startTime = intersection.get("start_time").toString();
            int planState = Integer.parseInt(intersection.get("plan_state").toString());
            Date beginDate = simpleDateFormat.parse(intersection.get("begin_date").toString());
            partnerDeviceShiftRelationDao.delete(tenantId, startTime, planState, beginDate);
        }
    }

    public List<Map<String, Object>> shiftList(String tenantId) {
        List<Map<String, Object>> mapList = partnerDeviceShiftRelationDao.getShiftList(tenantId);
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Map<String,Object>> objectMap = new HashMap<>();
        for (Map<String, Object> map : mapList) {
            int start = Integer.parseInt(map.get("start_time").toString().substring(0, 2));
            int end = Integer.parseInt(map.get("end_time").toString().substring(0, 2));
            int width;
            if (start > end) {
                width = 24 - start + end;
            } else {
                width = end - start;
            }
            String validTime = map.get("start_time").toString() + " - " + map.get("end_time").toString();
            if (!objectMap.containsKey(map.get("begin_date").toString())) {
                objectMap.put(map.get("begin_date").toString(), new HashMap<String, Object>() {{
                    put("begin_date", map.get("begin_date"));
                    put("width", width);
                    put("end_date", map.get("end_date"));
                    put("validTime", validTime);
                }});
            }else {
                Map<String,Object> oldMap = objectMap.get(map.get("begin_date").toString());
                oldMap.put("width", oldMap.get("width")+","+width);
                oldMap.put("validTime",oldMap.get("validTime")+","+ validTime);
                objectMap.put(map.get("begin_date").toString(),oldMap);
            }
        }

        for(String key:objectMap.keySet()){
            list.add(objectMap.get(key));
        }
        return list;
    }

    public List<Map<String, Object>> shiftListByBeginDate(String tenantId, Date beginDate) {
        List<Map<String, Object>> maps = partnerDeviceShiftRelationDao.getShiftListByBeginDate(tenantId, beginDate);
        return this.dataFormat(maps);
    }

    public List<Map<String, Object>> shiftListByEndDate(String tenantId, Date endDate) {
        List<Map<String, Object>> maps = partnerDeviceShiftRelationDao.getShiftListByEndDate(tenantId, endDate);
        return this.dataFormat(maps);
    }

    private List<Map<String, Object>> dataFormat(List<Map<String, Object>> maps) {
        List<Map<String, Object>> shifts = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            Map<String, Object> shiftMap = new HashMap<>();
            shiftMap.put("shift-start", map.get("start_time").toString());
            shiftMap.put("shift-end", map.get("end_time").toString());
            shiftMap.put("shift-name", String.valueOf(map.get("shift-name")));
            shiftMap.put("shift-user", String.valueOf(map.get("shift-lead")));
            shifts.add(shiftMap);
        }
        return shifts;
    }
}
